bitkeeper revision 1.1108.1.31 (4107adf2vp4n6dnsoTUjick0ruJYIQ)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 28 Jul 2004 13:45:22 +0000 (13:45 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 28 Jul 2004 13:45:22 +0000 (13:45 +0000)
get Linux 2.6 in dom0 working:
- tested with e100 driver and nfsroot

.rootkeys
linux-2.6.7-xen-sparse/arch/xen/i386/Makefile
linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile
linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c [new file with mode: 0644]
linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile [new file with mode: 0644]
linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c [new file with mode: 0644]
linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c [new file with mode: 0644]
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h [new file with mode: 0644]
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h

index 75f18a9865130083e6ff0190295587395565f043..8e0900c1d5310fd230a2c04fcd678f1af680e5ab 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ioport.c
 40f562382aC3_Gt4RG-4ZsfvDRUg3Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c
 40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c
+4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c
 40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c
 40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c
 40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/signal.c
 40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.7-xen-sparse/arch/xen/i386/mm/init.c
 41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c
 40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c
+4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile
+4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c
+4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c
 40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile
 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c
 40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c
 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile
 405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.7-xen-sparse/drivers/xen/net/network.c
 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h
+4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
 40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h
 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
 40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/hypervisor.h
index c06c8af0c15796cc6c547ed813aac91238ecd3ca..aa0870f67bc2a99996a2e345c1d361e187580e05 100644 (file)
@@ -72,13 +72,13 @@ core-y                                      += arch/xen/i386/kernel/ \
 # \
 #                                         arch/xen/$(mcore-y)/
 drivers-$(CONFIG_MATH_EMULATION)       += arch/i386/math-emu/
-drivers-$(CONFIG_PCI)                  += arch/i386/pci/
+drivers-$(CONFIG_PCI)                  += arch/xen/i386/pci/
 # must be linked after kernel/
 drivers-$(CONFIG_OPROFILE)             += arch/i386/oprofile/
 drivers-$(CONFIG_PM)                   += arch/i386/power/
 
 # for clean
-obj-   += kernel/
+obj-   += kernel/ mm/ pci/
 #obj-  += ../../i386/lib/ ../../i386/mm/ 
 #../../i386/$(mcore-y)/
 #obj-  += ../../i386/pci/ ../../i386/oprofile/ ../../i386/power/
index 816fcaa096479082f474df322148f8c3c2d6f44e..f867dc991926fc38a365f87aa1b73a4d43e3d595 100644 (file)
@@ -8,12 +8,12 @@ CFLAGS        += -Iarch/$(XENARCH)/kernel
 
 extra-y := head.o init_task.o vmlinux.lds.s
 
-obj-y  := traps.o irq.o ldt.o setup.o entry.o time.o process.o signal.o \
-               i386_ksyms.o
+obj-y  := traps.o irq.o ldt.o setup.o entry.o time.o pci-dma.o process.o \
+               signal.o i386_ksyms.o
 
 c-obj-y        := semaphore.o vm86.o \
                ptrace.o ioport.o sys_i386.o \
-               pci-dma.o i387.o dmi_scan.o bootflag.o \
+               i387.o dmi_scan.o bootflag.o \
                doublefault.o
 s-obj-y        :=
 
diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c
new file mode 100644 (file)
index 0000000..ab83af4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Dynamic DMA mapping support.
+ *
+ * On i386 there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in asm/pci.h.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+                          dma_addr_t *dma_handle, int gfp)
+{
+       void *ret;
+       /* ignore region specifiers */
+       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+               gfp |= GFP_DMA;
+
+       ret = (void *)__get_free_pages(gfp, get_order(size));
+
+       if (ret != NULL) {
+               memset(ret, 0, size);
+               *dma_handle = virt_to_bus(ret);
+       }
+       return ret;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+                        void *vaddr, dma_addr_t dma_handle)
+{
+       free_pages((unsigned long)vaddr, get_order(size));
+}
diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile
new file mode 100644 (file)
index 0000000..175f5f4
--- /dev/null
@@ -0,0 +1,31 @@
+XENARCH        := $(subst ",,$(CONFIG_XENARCH))
+
+CFLAGS += -Iarch/$(XENARCH)/pci
+
+c-obj-y                                := i386.o
+
+c-obj-$(CONFIG_PCI_BIOS)               += pcbios.o
+c-obj-$(CONFIG_PCI_MMCONFIG)   += mmconfig.o
+obj-$(CONFIG_PCI_DIRECT)       += direct.o
+
+c-pci-y                                := fixup.o
+c-pci-$(CONFIG_ACPI_PCI)       += acpi.o
+c-pci-y                                += legacy.o
+pci-y                          += irq.o
+
+c-pci-$(CONFIG_X86_VISWS)      := visws.o fixup.o
+pci-$(CONFIG_X86_VISWS)                :=
+c-pci-$(CONFIG_X86_NUMAQ)      := numa.o
+pci-$(CONFIG_X86_NUMAQ)                := irq.o
+
+obj-y                          += $(pci-y)
+c-obj-y                                += $(c-pci-y) common.o
+
+c-link :=
+
+$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)):
+       @ln -fsn $(srctree)/arch/i386/pci/$(notdir $@) $@
+
+obj-y  += $(c-obj-y)
+
+clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c
new file mode 100644 (file)
index 0000000..6612213
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * direct.c - Low-level direct PCI config space access
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci.h"
+
+#include <asm/hypervisor-ifs/hypervisor-if.h>
+#include <asm/hypervisor-ifs/physdev.h>
+
+/*
+ * Functions for accessing PCI configuration space with type xen accesses
+ */
+
+static int pci_conf_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
+{
+       unsigned long flags;
+       physdev_op_t op;
+       int ret;
+
+       if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       op.cmd = PHYSDEVOP_PCI_CFGREG_READ;
+       op.u.pci_cfgreg_read.bus  = bus;
+       op.u.pci_cfgreg_read.dev  = (devfn & ~0x7) >> 3;
+       op.u.pci_cfgreg_read.func = devfn & 0x7;
+       op.u.pci_cfgreg_read.reg  = reg;
+       op.u.pci_cfgreg_read.len  = len;
+
+       ret = HYPERVISOR_physdev_op(&op);
+       if (ret == 0)
+               *value = op.u.pci_cfgreg_read.value;
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return ret;
+}
+
+static int pci_conf_write (int seg, int bus, int devfn, int reg, int len, u32 value)
+{
+       unsigned long flags;
+       physdev_op_t op;
+       int ret;
+
+       if ((bus > 255) || (devfn > 255) || (reg > 255)) 
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE;
+       op.u.pci_cfgreg_write.bus   = bus;
+       op.u.pci_cfgreg_write.dev   = (devfn & ~0x7) >> 3;
+       op.u.pci_cfgreg_write.func  = devfn & 0x7;
+       op.u.pci_cfgreg_write.reg   = reg;
+       op.u.pci_cfgreg_write.len   = len;
+       op.u.pci_cfgreg_write.value = value;
+
+       ret = HYPERVISOR_physdev_op(&op);
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return ret;
+}
+
+struct pci_raw_ops pci_direct_xen = {
+       .read =         pci_conf_read,
+       .write =        pci_conf_write,
+};
+
+
+static int __init pci_direct_init(void)
+{
+
+        printk(KERN_INFO "PCI: Using configuration type Xen\n");
+        raw_pci_ops = &pci_direct_xen;
+        return 0;
+}
+
+arch_initcall(pci_direct_init);
diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c
new file mode 100644 (file)
index 0000000..f6d49f8
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ *     Low-Level PCI Support for PC -- Routing of Interrupts
+ *
+ *     (c) 1999--2000 Martin Mares <mj@ucw.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/io_apic.h>
+#include <asm/hw_irq.h>
+
+#include "pci.h"
+
+#include <asm/hypervisor-ifs/hypervisor-if.h>
+#include <asm/hypervisor-ifs/physdev.h>
+
+int broken_hp_bios_irq9;
+
+/*
+ * Never use: 0, 1, 2 (timer, keyboard, and cascade)
+ * Avoid using: 13, 14 and 15 (FP error and IDE).
+ * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
+ */
+unsigned int pcibios_irq_mask = 0xfff8;
+
+static int pirq_penalty[16] = {
+       1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
+       0, 0, 0, 0, 1000, 100000, 100000, 100000
+};
+
+int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+
+
+static int __init pcibios_irq_init(void)
+{
+       int bus;
+       physdev_op_t op;
+
+       DBG("PCI: IRQ init\n");
+
+       if (pcibios_enable_irq || raw_pci_ops == NULL)
+               return 0;
+
+       op.cmd = PHYSDEVOP_PCI_PROBE_ROOT_BUSES;
+       if (HYPERVISOR_physdev_op(&op) != 0) {
+               printk(KERN_WARNING "PCI: System does not support PCI\n");
+               return 0;
+       }
+
+       printk(KERN_INFO "PCI: Probing PCI hardware\n");
+       for (bus = 0; bus < 256; bus++)
+               if (test_bit(bus, (unsigned long *)
+                       &op.u.pci_probe_root_buses.busmask[0]))
+                       (void)pcibios_scan_root(bus);
+
+       pcibios_enable_irq = pirq_enable_irq;
+
+       return 0;
+}
+
+subsys_initcall(pcibios_irq_init);
+
+
+void pcibios_penalize_isa_irq(int irq)
+{
+       /*
+        *  If any ISAPnP device reports an IRQ in its list of possible
+        *  IRQ's, we try to avoid assigning it to PCI devices.
+        */
+       pirq_penalty[irq] += 100;
+}
+
+int pirq_enable_irq(struct pci_dev *dev)
+{
+       int err;
+       u8  pin;
+       physdev_op_t op;
+
+       /* Inform Xen that we are going to use this device. */
+       op.cmd = PHYSDEVOP_PCI_INITIALISE_DEVICE;
+       op.u.pci_initialise_device.bus  = dev->bus->number;
+       op.u.pci_initialise_device.dev  = PCI_SLOT(dev->devfn);
+       op.u.pci_initialise_device.func = PCI_FUNC(dev->devfn);
+       if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
+               return err;
+
+       /* Now we can bind to the very final IRQ line. */
+       pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &pin);
+       dev->irq = pin;
+
+       /* Sanity-check that an interrupt-producing device is routed
+        * to an IRQ. */
+       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       if (pin != 0) {
+               if (dev->irq != 0)
+                       printk(KERN_INFO "PCI: Obtained IRQ %d for device %s\n",
+                           dev->irq, dev->slot_name);
+               else
+                       printk(KERN_WARNING "PCI: No IRQ known for interrupt "
+                           "pin %c of device %s.\n", 'A' + pin - 1,
+                           dev->slot_name);
+       }
+
+       return 0;
+}
+
+int pci_vector_resources(int last, int nr_released)
+{
+       int count = nr_released;
+
+       int next = last;
+       int offset = (last % 8);
+
+       while (next < FIRST_SYSTEM_VECTOR) {
+               next += 8;
+#ifdef CONFIG_X86_64
+               if (next == IA32_SYSCALL_VECTOR)
+                       continue;
+#else
+               if (next == SYSCALL_VECTOR)
+                       continue;
+#endif
+               count++;
+               if (next >= FIRST_SYSTEM_VECTOR) {
+                       if (offset%8) {
+                               next = FIRST_DEVICE_VECTOR + offset;
+                               offset++;
+                               continue;
+                       }
+                       count--;
+               }
+       }
+
+       return count;
+}
diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
new file mode 100644 (file)
index 0000000..9d2f2ce
--- /dev/null
@@ -0,0 +1,163 @@
+#ifndef _ASM_I386_DMA_MAPPING_H
+#define _ASM_I386_DMA_MAPPING_H
+
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+                          dma_addr_t *dma_handle, int flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+                        void *vaddr, dma_addr_t dma_handle);
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       flush_write_buffers();
+       return virt_to_bus(ptr);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+                enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+          enum dma_data_direction direction)
+{
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       for (i = 0; i < nents; i++ ) {
+               BUG_ON(!sg[i].page);
+
+               sg[i].dma_address = page_to_machine(sg[i].page) + sg[i].offset;
+       }
+
+       flush_write_buffers();
+       return nents;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+            size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       return page_to_machine(page) + offset;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+            enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+                       enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+                       enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+                             unsigned long offset, size_t size,
+                             enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+                                unsigned long offset, size_t size,
+                                enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+                   enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+                   enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+       return 0;
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if(mask < 0x00ffffff)
+                return 0;
+
+       return 1;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+       if(!dev->dma_mask || !dma_supported(dev, mask))
+               return -EIO;
+
+       *dev->dma_mask = mask;
+
+       return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+       /* no easy way to get cache size on all x86, so return the
+        * maximum possible, to be safe */
+       return (1 << L1_CACHE_SHIFT_MAX);
+}
+
+#define dma_is_consistent(d)   (1)
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+              enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+#endif
index 81482eb3f4723cc5b35884785ae6b388ca4d4a9a..321d4788e1442272bc4022a33a00ec78c3ca1f45 100644 (file)
@@ -86,6 +86,7 @@ static inline void * phys_to_virt(unsigned long address)
  * Change "struct page" to physical address.
  */
 #define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+#define page_to_machine(page) (phys_to_machine(page_to_phys(page)))
 
 extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);